#include "LogClient.h"
#include <cstring>
#include <chrono>
#include <sstream>
#include <iomanip>
#include <iostream>
#include <QJsonDocument>
#include <QJsonObject>
#include <QCoreApplication>



// 单例实例获取
LogClient& LogClient::getInstance() {
    static LogClient instance;
    return instance;
}

// 构造函数
LogClient::LogClient()
    : QObject(nullptr),
      webSocket(nullptr),
      connected(false),
      running(false),
      autoReconnect(true),
      reconnectIntervalMs(5000),
      reconnectTimer(nullptr) {
    // 确保在主线程中创建Qt对象
    moveToThread(QCoreApplication::instance()->thread());
}

// 析构函数
LogClient::~LogClient() {
    shutdown();
}

// 初始化WebSocket连接
bool LogClient::initialize(const std::string& url) {
    if (running) {
        return false; // 已经初始化
    }
    
    serverUrl = url;
    running = true;
    
    // 使用QMetaObject::invokeMethod确保在主线程中创建Qt对象
    QMetaObject::invokeMethod(this, [this]() {
        // 创建重连定时器（如果还没有创建）
        if (!reconnectTimer) {
            reconnectTimer = new QTimer(this);
            reconnectTimer->setSingleShot(true);
            QObject::connect(reconnectTimer, &QTimer::timeout, this, &LogClient::onReconnectTimer);
        }
        
        // 创建QWebSocket实例
        if (!webSocket) {
            webSocket = new QWebSocket();
            
            // 连接信号和槽
            QObject::connect(webSocket, &QWebSocket::connected, this, &LogClient::onConnected);
            QObject::connect(webSocket, &QWebSocket::disconnected, this, &LogClient::onDisconnected);
            QObject::connect(webSocket, &QWebSocket::textMessageReceived, this, &LogClient::onTextMessageReceived);
            QObject::connect(webSocket, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error),
                    this, &LogClient::onError);
        }
        
        // 尝试连接
        connect();
    }, Qt::QueuedConnection);
    
    // 启动发送线程
    sendThread = std::thread(&LogClient::sendThreadFunc, this);
    
    return true;
}

// 关闭连接并清理资源
void LogClient::shutdown() {
    if (!running) {
        return;
    }
    
    // 停止线程
    running = false;
    
    // 停止重连定时器
    if (reconnectTimer) {
        reconnectTimer->stop();
    }
    
    // 唤醒发送线程
    queueCondition.notify_all();
    
    // 等待线程结束
    if (sendThread.joinable()) {
        sendThread.join();
    }
    
    // 断开连接
    disconnect();
    
    // 清理WebSocket
    if (webSocket) {
        webSocket->deleteLater();
        webSocket = nullptr;
    }
}

// 发送日志
void LogClient::log(LogLevel level, const std::string& module, const std::string& message) {
    if (!running) {
        return;
    }
    
    // 创建日志条目
    LogEntry entry;
    entry.level = level;
    entry.module = module;
    entry.message = message;
    
    // 获取设备ID和会话ID
    {
        std::lock_guard<std::mutex> lock(deviceMutex);
        entry.deviceId = deviceId;
        entry.sessionId = sessionId;
    }
    
    // 添加时间戳（ISO 8601 UTC格式）
    auto now = std::chrono::system_clock::now();
    auto now_c = std::chrono::system_clock::to_time_t(now);
    auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;
    
    std::stringstream ss;
    ss << std::put_time(std::gmtime(&now_c), "%Y-%m-%dT%H:%M:%S");
    ss << '.' << std::setfill('0') << std::setw(3) << now_ms.count();
    ss << 'Z';  // UTC时间标识
    entry.timestamp = ss.str();
    
    // 添加到队列
    {
        std::lock_guard<std::mutex> lock(queueMutex);
        logQueue.push(entry);
    }
    
    // 通知发送线程
    queueCondition.notify_one();
}

// 快捷日志方法
void LogClient::debug(const std::string& module, const std::string& message) {
    log(LogLevel::DEBUG, module, message);
}

void LogClient::info(const std::string& module, const std::string& message) {
    log(LogLevel::INFO, module, message);
}

void LogClient::warning(const std::string& module, const std::string& message) {
    log(LogLevel::WARNING, module, message);
}

void LogClient::error(const std::string& module, const std::string& message) {
    log(LogLevel::LOG_ERROR, module, message);
}

void LogClient::exception(const std::string& module, const std::string& message) {
    log(LogLevel::EXCEPTION, module, message);
}

void LogClient::emergency(const std::string& module, const std::string& message) {
    log(LogLevel::EMERGENCY, module, message);
}

// 设置连接状态回调
void LogClient::setConnectionCallback(std::function<void(bool)> callback) {
    connectionCallback = callback;
}

// 检查连接状态
bool LogClient::isConnected() const {
    return connected;
}

// 设置自动重连
void LogClient::setAutoReconnect(bool autoReconn, int reconnectIntervalMilliseconds) {
    autoReconnect = autoReconn;
    reconnectIntervalMs = reconnectIntervalMilliseconds;
}

// 设置设备ID
void LogClient::setDeviceId(const std::string& id) {
    std::lock_guard<std::mutex> lock(deviceMutex);
    deviceId = id;
}

// 设置会话ID
void LogClient::setSessionId(const std::string& id) {
    std::lock_guard<std::mutex> lock(deviceMutex);
    sessionId = id;
}

// 获取当前设备ID
std::string LogClient::getDeviceId() const {
    std::lock_guard<std::mutex> lock(deviceMutex);
    return deviceId;
}

// 获取当前会话ID
std::string LogClient::getSessionId() const {
    std::lock_guard<std::mutex> lock(deviceMutex);
    return sessionId;
}

// 连接到WebSocket服务器
bool LogClient::connect() {
    if (connected) {
        return false;
    }
    
    // 确保在主线程中执行WebSocket操作
    QMetaObject::invokeMethod(this, [this]() {
        if (webSocket && !connected) {
            QUrl url(QString::fromStdString(serverUrl));
            webSocket->open(url);
        }
    }, Qt::QueuedConnection);
    
    return true;
}

// 断开连接
void LogClient::disconnect() {
    // 确保在主线程中执行WebSocket操作
    QMetaObject::invokeMethod(this, [this]() {
        if (webSocket && connected) {
            webSocket->close();
        }
    }, Qt::QueuedConnection);
}

// QWebSocket信号处理槽
void LogClient::onConnected() {
    connected = true;
    std::cout << "LogClient: Connected to WebSocket server" << std::endl;
    
    // 停止重连定时器
    if (reconnectTimer) {
        reconnectTimer->stop();
    }
    
    // 发送设备注册消息
    sendDeviceRegistration();
    
    // 调用连接回调
    if (connectionCallback) {
        connectionCallback(true);
    }
}

void LogClient::onDisconnected() {
    connected = false;
    std::cout << "LogClient: Disconnected from WebSocket server" << std::endl;
    
    // 调用连接回调
    if (connectionCallback) {
        connectionCallback(false);
    }
    
    // 如果启用自动重连且仍在运行，启动重连定时器
    if (autoReconnect && running && reconnectTimer) {
        reconnectTimer->start(reconnectIntervalMs);
    }
}

void LogClient::onTextMessageReceived(const QString &message) {
    // 处理服务器发送的消息（如果需要）
    std::cout << "LogClient: Received message: " << message.toStdString() << std::endl;
}

void LogClient::onError(QAbstractSocket::SocketError error) {
    std::cout << "LogClient: WebSocket error: " << static_cast<int>(error) << std::endl;
    
    connected = false;
    
    // 调用连接回调
    if (connectionCallback) {
        connectionCallback(false);
    }
    
    // 如果启用自动重连且仍在运行，启动重连定时器
    if (autoReconnect && running && reconnectTimer) {
        reconnectTimer->start(reconnectIntervalMs);
    }
}

void LogClient::onReconnectTimer() {
    if (!connected && running) {
        std::cout << "LogClient: Attempting to reconnect..." << std::endl;
        connect();
    }
}

// 发送线程函数
void LogClient::sendThreadFunc() {
    while (running) {
        // 等待队列中有日志或者线程被要求停止
        std::unique_lock<std::mutex> lock(queueMutex);
        queueCondition.wait(lock, [this] { return !running || !logQueue.empty(); });
        
        // 如果线程被要求停止且队列为空，退出
        if (!running && logQueue.empty()) {
            break;
        }
        
        // 获取队列中的日志
        LogEntry entry = logQueue.front();
        logQueue.pop();
        lock.unlock();
        
        // 如果已连接，发送日志
        if (connected && webSocket) {
            // 将日志转换为JSON
            std::string json = logEntryToJson(entry);
            
            // 确保在主线程中发送数据
            QMetaObject::invokeMethod(this, [this, json]() {
                if (webSocket && connected) {
                    webSocket->sendTextMessage(QString::fromStdString(json));
                }
            }, Qt::QueuedConnection);
        } else {
            // 未连接，输出到控制台作为fallback
            std::string levelStr;
            switch (entry.level) {
                case LogLevel::DEBUG: levelStr = "DEBUG"; break;
                case LogLevel::INFO: levelStr = "INFO"; break;
                case LogLevel::WARNING: levelStr = "WARNING"; break;
                case LogLevel::LOG_ERROR: levelStr = "ERROR"; break;
                case LogLevel::EXCEPTION: levelStr = "EXCEPTION"; break;
                case LogLevel::EMERGENCY: levelStr = "EMERGENCY"; break;
            }
            std::cout << "[" << entry.timestamp << "] [" << levelStr << "] [" << entry.module << "] " << entry.message << std::endl;
        }
    }
}

// 将日志条目转换为JSON字符串
std::string LogClient::logEntryToJson(const LogEntry& entry) {
    // 将日志级别转换为字符串
    std::string levelStr;
    switch (entry.level) {
        case LogLevel::DEBUG:
            levelStr = "debug";
            break;
        case LogLevel::INFO:
            levelStr = "info";
            break;
        case LogLevel::WARNING:
            levelStr = "warning";
            break;
        case LogLevel::LOG_ERROR:
            levelStr = "error";
            break;
        case LogLevel::EXCEPTION:
            levelStr = "exception";
            break;
        case LogLevel::EMERGENCY:
            levelStr = "emergency";
            break;
        default:
            levelStr = "info";
            break;
    }
    
    // 构建与网页版一致的JSON格式
    QJsonObject dataObj;
    dataObj["level"] = QString::fromStdString(levelStr);
    dataObj["module"] = QString::fromStdString(entry.module);
    dataObj["message"] = QString::fromStdString(entry.message);
    dataObj["timestamp"] = QString::fromStdString(entry.timestamp);
    
    // 添加设备ID（如果存在）
    if (!entry.deviceId.empty()) {
        dataObj["deviceId"] = QString::fromStdString(entry.deviceId);
    }
    
    // 添加会话ID（如果存在）
    if (!entry.sessionId.empty()) {
        dataObj["sessionId"] = QString::fromStdString(entry.sessionId);
    }
    
    QJsonObject jsonObj;
    jsonObj["type"] = "log";
    jsonObj["data"] = dataObj;
    
    QJsonDocument doc(jsonObj);
    return doc.toJson(QJsonDocument::Compact).toStdString();
}

void LogClient::sendDeviceRegistration() {
    if (!webSocket || !connected) {
        return;
    }
    
    std::lock_guard<std::mutex> lock(deviceMutex);
    
    // 创建设备注册消息
    QJsonObject jsonObj;
    jsonObj["type"] = "device_register";
    
    QJsonObject dataObj;
    if (!deviceId.empty()) {
        dataObj["deviceName"] = QString::fromStdString(deviceId);
        dataObj["description"] = QString::fromStdString("C++ Log Client - " + deviceId);
    } else {
        dataObj["deviceName"] = "Unknown Device";
        dataObj["description"] = "C++ Log Client - Unknown Device";
    }
    
    jsonObj["data"] = dataObj;
    
    QJsonDocument doc(jsonObj);
    QString message = doc.toJson(QJsonDocument::Compact);
    
    // 发送设备注册消息
    webSocket->sendTextMessage(message);
    
    std::cout << "LogClient: Sent device registration: " << message.toStdString() << std::endl;
}

// MOC文件将由CMake自动生成和包含